<template>
    <div
        class="page_root"
        :key="queryUpdateFlag"
        data-page-name="月度目标管理(新版)"
        data-page-identification="c_i0ngsrcxvq"
    >
        <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
            <!-- begin vid_p2x31ulxw6 自定义模板_gufjjaz2ct -->
            <!--          查看任务-->
            <a-modal
                width="100vw"
                v-model:visible="taskMoadlVisible"
                :mask-closable="false"
                :keyboard="false"
                centered
                destroy-on-close
                :footer="null"
            >
                <TaskJump :storyId="taskModalId" />
            </a-modal>
            <!--          查看任务-->
            <!--          新建/编辑年度目标-->
            <a-modal
                v-model:visible="targetState.addOrEditYearGoalVisible"
                :title="targetState.yearGoalTitle"
                @ok="handleSubmitYearGoal"
                @cancel="resetYearGoal"
                :mask-closable="false"
                :keyboard="false"
                centered
                width="800px"
                destroy-on-close
                :ok-button-props="{ loading: targetState.addOrEditYearGoalLoading }"
            >
                <a-form :model="targetState.yearGoalModalForm" ref="yearGoalRef">
                    <a-row :gutter="24">
                        <a-col :span="24">
                            <a-form-item
                                label="目标年份"
                                name="year"
                                :rules="[{ required: true, message: '请选择目标年份', trigger: 'blur' }]"
                            >
                                <a-date-picker
                                    :disabled="currentEditYearGoal.id"
                                    style="width: 100%"
                                    picker="year"
                                    :allow-clear="false"
                                    value-format="YYYY"
                                    v-model:value="targetState.yearGoalModalForm.year"
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="12">
                            <a-form-item
                                label="项目类型"
                                :rules="[{ required: true, message: '请选择项目类型', trigger: 'blur' }]"
                                name="projectType"
                            >
                                <a-select
                                    :options="[
                                        {
                                            label: '产品研发',
                                            value: '产品研发'
                                        },
                                        {
                                            label: '交付',
                                            value: '交付'
                                        },
                                        {
                                            label: '市场',
                                            value: '市场'
                                        }
                                    ]"
                                    :placeholder="selectHolder"
                                    v-model:value="targetState.yearGoalModalForm.projectType"
                                    @change="
                                        () => {
                                            targetState.yearGoalModalForm.projectId = undefined
                                        }
                                    "
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="12">
                            <a-form-item
                                label="项目名称"
                                :rules="[{ required: true, message: '请选择项目名称', trigger: 'blur' }]"
                                name="projectId"
                            >
                                <a-select
                                    :options="targetState.projectList"
                                    v-model:value="targetState.yearGoalModalForm.projectId"
                                    :filterOption="
                                        (input, option) => {
                                            return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                        }
                                    "
                                    :placeholder="selectHolder"
                                    @focus="getYearProjectListAccordingType"
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="24">
                            <a-form-item
                                label="年度目标"
                                name="goal"
                                :rules="[{ required: true, message: '请输入年度目标', trigger: 'blur' }]"
                            >
                                <a-textarea
                                    v-model:value="targetState.yearGoalModalForm.goal"
                                    :placeholder="inputHolder"
                                    :rows="4"
                                />
                            </a-form-item>
                        </a-col>
                    </a-row>
                </a-form>
            </a-modal>
            <!--          新建/编辑年度目标-->
            <!--            甘特图-->
            <a-modal
                :visible="targetState.ganteVisible"
                title="目标甘特图"
                :footer="null"
                centered
                @cancel="cancelGante"
                width="100%"
                :body-style="{
                    maxHeight: '800px',
                    overflowY: 'auto'
                }"
            >
                <Gante v-if="targetState.ganteVisible" :time="gantMonth" :projectName="gantProjectName" />
            </a-modal>
            <!--            甘特图-->
            <!--            查看问题-->
            <a-modal
                :visible="showMsgState.visible"
                title="用户故事描述"
                :footer="null"
                centered
                @cancel="cancelShowMsg"
                width="1000px"
                :body-style="{
                    maxHeight: '800px',
                    overflowY: 'auto'
                }"
            >
                <div class="item-content" v-html="getHtmlContent(showMsgState.msg)"> </div>
            </a-modal>
            <!--            查看问题-->
            <!--            新建/编辑用户故事-->
            <a-modal
                :visible="milepostState.addOrEditVisible"
                :title="milepostState.addOrEditTitle"
                centered
                :mask-closable="false"
                destroy-on-close
                :body-style="{
                    maxHeight: '800px',
                    overflowY: 'auto'
                }"
                width="1000px"
                @cancel="cancelStory"
            >
                <template #footer>
                    <a-button type="primary" @click="cancleMbTask"> 取消</a-button>
                    <a-button
                        type="primary"
                        v-if="
                            milepostState.current == 1 &&
                            milepostState.modalForm.templateTaskId?.length > 0 &&
                            !currentData.id
                        "
                        @click="getTask"
                        :loading="milepostState.nextLoading"
                    >
                        下一步</a-button
                    >
                    <a-button type="primary" v-if="milepostState.current == 2" @click="milepostState.current = 1">
                        上一步</a-button
                    >
                    <a-button
                        type="primary"
                        @click="confirmMbTask"
                        v-if="
                            milepostState.current == 2 ||
                            (milepostState.modalForm.templateTaskId?.length == 0 && milepostState.current == 1)
                        "
                        :loading="milepostState.okLoading"
                    >
                        确定</a-button
                    >
                </template>
                <div class="form-model">
                    <a-form :model="milepostState.modalForm" ref="formRef" :rules="rules">
                        <a-row v-if="milepostState.current == 1">
                            <a-col :span="12">
                                <a-form-item label="月份">
                                    <a-date-picker
                                        v-model:value="milepostState.modalForm.monthlyGoalTargetMonth"
                                        value-format="YYYY-MM"
                                        picker="month"
                                        style="width: 100%"
                                        @change="milepostState.modalForm.projectMonthlyGoalManagementId = undefined"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="月度子目标">
                                    <a-select
                                        :options="milepostState.targetList"
                                        v-model:value="milepostState.modalForm.projectMonthlyGoalManagementId"
                                        show-search
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        allow-clear
                                        @focus="getTarget"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item label="用户故事名称" name="storyName">
                                    <a-input
                                        v-model:value="milepostState.modalForm.storyName"
                                        :placeholder="inputHolder"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="计划起止时间">
                                    <a-range-picker
                                        style="width: 100%"
                                        v-model:value="milepostState.modalForm.timeRangeList"
                                        valueFormat="YYYY-MM-DD"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="优先级"
                                    name="priority"
                                    :rules="[{ required: true, msssage: '请选择优先级', trigger: 'blur' }]"
                                >
                                    <a-select
                                        :options="[
                                            {
                                                label: 'P0',
                                                value: 'P0'
                                            },
                                            {
                                                label: 'P1',
                                                value: 'P1'
                                            },
                                            {
                                                label: 'P2',
                                                value: 'P2'
                                            },
                                            {
                                                label: 'P3',
                                                value: 'P3'
                                            }
                                        ]"
                                        :placeholder="selectHolder"
                                        v-model:value="milepostState.modalForm.priority"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item label="描述" name="labels">
                                    <QuillEditor
                                        v-model:content="milepostState.modalForm.description"
                                        ref="quillEditor"
                                        :options="editorOption"
                                        class="quill-editor"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item label="标签" name="labels">
                                    <a-input
                                        v-model:value="milepostState.modalForm.labels"
                                        show-count
                                        :placeholder="inputHolder"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24" v-if="!currentData.id">
                                <a-form-item
                                    label="功能简称"
                                    name="functionAbbreviation"
                                    :rules="[
                                        {
                                            required: milepostState.modalForm.templateTaskId.length > 0 ? true : false,
                                            message: '请输入功能简称',
                                            trigger: 'blur'
                                        }
                                    ]"
                                >
                                    <a-input
                                        :placeholder="inputHolder"
                                        v-model:value="milepostState.modalForm.functionAbbreviation"
                                        maxlength="10"
                                        show-count
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24" v-if="!currentData.id">
                                <a-form-item label="SOP任务">
                                    <a-tree-select
                                        v-model:value="milepostState.modalForm.templateTaskId"
                                        show-search
                                        multiple
                                        treeCheckable
                                        style="width: 100%"
                                        placeholder="请选择"
                                        allow-clear
                                        treeDefaultExpandAll
                                        :tree-data="milepostState.treeData"
                                        :fieldNames="{
                                            children: 'children',
                                            label: 'taskName',
                                            value: 'taskId',
                                            key: 'taskId'
                                        }"
                                        :filterTreeNode="
                                            (inputValue, treeNode) => {
                                                return (
                                                    treeNode.taskName.toLowerCase().indexOf(inputValue.toLowerCase()) >=
                                                    0
                                                )
                                            }
                                        "
                                        :max-tag-count="7"
                                        @focus="getTreeData"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item label="备注">
                                    <a-textarea
                                        v-model:value="milepostState.modalForm.remarks"
                                        :placeholder="inputHolder"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div v-else>
                            <div
                                v-for="(item, index) in milepostState.modalForm.taskList"
                                :key="index"
                                class="form-item"
                            >
                                <div class="form-content">
                                    <a-row class="one-line">
                                        <a-col :span="24">
                                            <a-form-item
                                                label="任务名称"
                                                :name="['taskList', index, 'taskName']"
                                                :rules="[
                                                    {
                                                        required: true,
                                                        message: '请输入任务名称!'
                                                    },
                                                    {
                                                        validator: () => {
                                                            if (milepostState.modalForm.taskList[index].taskName) {
                                                                if (
                                                                    milepostState.modalForm.taskList[
                                                                        index
                                                                    ].taskName.trim()
                                                                ) {
                                                                    return PromiseProxy.resolve()
                                                                } else {
                                                                    return PromiseProxy.reject('请输入任务名称!')
                                                                }
                                                            } else {
                                                                return PromiseProxy.resolve()
                                                            }
                                                        }
                                                    }
                                                ]"
                                            >
                                                <a-input
                                                    disabled
                                                    :placeholder="inputHolder"
                                                    v-model:value="milepostState.modalForm.taskList[index].taskName"
                                                />
                                            </a-form-item>
                                        </a-col>
                                    </a-row>

                                    <a-row>
                                        <a-col :span="12">
                                            <a-form-item
                                                label="预计投入工时"
                                                :name="['taskList', index, 'workingHours']"
                                                :rules="[
                                                    { required: true, message: '请输入预计投入工时!', trigger: 'blur' },
                                                    {
                                                        pattern: /^(0\.5|[1-9](\d*)?(\.5)?(\.0)?)$/,
                                                        message: '请输入大于0的数字(支持0.5的倍数)',
                                                        trigger: 'blur'
                                                    }
                                                ]"
                                            >
                                                <a-input
                                                    placeholder="请输入工时(支持0.5的数字)"
                                                    v-model:value="milepostState.modalForm.taskList[index].workingHours"
                                                    :min="0"
                                                    type="number"
                                                    suffix="小时"
                                                />
                                            </a-form-item>
                                        </a-col>
                                        <a-col :span="12">
                                            <a-form-item
                                                label="任务起止时间"
                                                :name="['taskList', index, 'allTime']"
                                                :rules="{ required: true, message: '请选择任务起止时间!' }"
                                            >
                                                <a-range-picker
                                                    style="width: 100%"
                                                    v-model:value="milepostState.modalForm.taskList[index].allTime"
                                                    valueFormat="YYYY-MM-DD"
                                                />
                                            </a-form-item>
                                        </a-col>
                                    </a-row>
                                    <a-row>
                                        <a-col :span="12">
                                            <a-form-item
                                                label="任务负责人"
                                                :name="['taskList', index, 'taskOwner']"
                                                :rules="{ required: true, message: '请选择任务负责人!' }"
                                            >
                                                <a-select
                                                    :placeholder="selectHolder"
                                                    v-model:value="milepostState.modalForm.taskList[index].taskOwner"
                                                    showSearch
                                                    :options="peopleList"
                                                    :field-names="{ label: 'label', value: 'value' }"
                                                    :filter-option="
                                                        (input, option) => {
                                                            return (
                                                                option.label
                                                                    .toLowerCase()
                                                                    .indexOf(input.toLowerCase()) >= 0
                                                            )
                                                        }
                                                    "
                                                />
                                            </a-form-item>
                                        </a-col>
                                        <a-col :span="12">
                                            <a-form-item
                                                label="审核员"
                                                :name="['taskList', index, 'assessorName']"
                                                :rules="{ required: true, message: '请选择审核员!' }"
                                            >
                                                <a-select
                                                    :placeholder="selectHolder"
                                                    v-model:value="milepostState.modalForm.taskList[index].assessorName"
                                                    showSearch
                                                    :options="peopleList"
                                                    :field-names="{ label: 'label', value: 'value' }"
                                                    :filter-option="
                                                        (input, option) => {
                                                            return (
                                                                option.label
                                                                    .toLowerCase()
                                                                    .indexOf(input.toLowerCase()) >= 0
                                                            )
                                                        }
                                                    "
                                                />
                                            </a-form-item>
                                        </a-col>
                                    </a-row>
                                    <a-row class="one-line">
                                        <a-col :span="24">
                                            <a-form-item
                                                label="任务执行人"
                                                :name="['taskList', index, 'taskParticipantList']"
                                                :rules="{ required: true, message: '请选择任务参与人!' }"
                                            >
                                                <a-select
                                                    :placeholder="selectHolder"
                                                    v-model:value="
                                                        milepostState.modalForm.taskList[index].taskParticipantList
                                                    "
                                                    showSearch
                                                    mode="multiple"
                                                    :options="peopleList"
                                                    :field-names="{ label: 'label', value: 'value' }"
                                                    :filter-option="
                                                        (input, option) => {
                                                            return (
                                                                option.label
                                                                    .toLowerCase()
                                                                    .indexOf(input.toLowerCase()) >= 0
                                                            )
                                                        }
                                                    "
                                                />
                                            </a-form-item>
                                        </a-col>
                                    </a-row>
                                    <a-row>
                                        <a-col v-if="taskPeopleList.length > 0">
                                            <div style="width: 600px; margin-left: 115px; margin-bottom: 28px">
                                                <a
                                                    href="javascript:;"
                                                    v-for="(item, num) in taskPeopleList"
                                                    @click="handlerAddPtMbPeople(item.value, index)"
                                                    ><span style="margin: 0 5px">{{ item.value }}</span></a
                                                >
                                            </div>
                                        </a-col>
                                    </a-row>
                                    <a-row class="one-line">
                                        <a-col :span="24">
                                            <a-form-item label="备注">
                                                <a-textarea
                                                    v-model:value="milepostState.modalForm.taskList[index].remark"
                                                    :placeholder="inputHolder"
                                                />
                                            </a-form-item>
                                        </a-col>
                                    </a-row>
                                </div>
                            </div>
                        </div>
                    </a-form>
                </div>
            </a-modal>
            <!--            新建/编辑用户故事-->
            <!--        新建/编辑月度目标    -->
            <a-modal
                :visible="targetState.addOrEditVisible"
                :title="targetState.addOrEditTitle"
                centered
                width="800px"
                :body-style="{
                    maxHeight: '800px',
                    overflowY: 'auto'
                }"
                destroy-on-close
                @ok="submitTarget"
                @cancel="cancelTarget"
                :mask-closable="false"
                :ok-button-props="{ loading: targetState.targetLoadog }"
            >
                <div class="modal-form">
                    <a-form :model="targetState.modalForm" ref="targetFormRef">
                        <a-row>
                            <a-col :span="11">
                                <a-form-item
                                    label="目标月份"
                                    :rules="[{ required: true, message: '请选择目标月份', trigger: 'blur' }]"
                                    name="targetMonth"
                                >
                                    <a-date-picker
                                        :disabled="currentEditData.overallProjectId"
                                        style="width: 100%"
                                        picker="month"
                                        v-model:value="targetState.modalForm.targetMonth"
                                        value-format="YYYY-MM"
                                        @change="
                                            () => {
                                                if (targetState.modalForm.projectId) {
                                                    getLastPeople()
                                                }
                                            }
                                        "
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="11" />
                            <a-col :span="11">
                                <a-form-item
                                    label="项目类型"
                                    :rules="[{ required: true, message: '请选择项目类型', trigger: 'blur' }]"
                                    name="projectType"
                                >
                                    <a-select
                                        :disabled="currentEditData.overallProjectId"
                                        :options="[
                                            {
                                                label: '产品研发',
                                                value: '产品研发'
                                            },
                                            {
                                                label: '交付',
                                                value: '交付'
                                            },
                                            {
                                                label: '市场',
                                                value: '市场'
                                            }
                                        ]"
                                        :placeholder="selectHolder"
                                        v-model:value="targetState.modalForm.projectType"
                                        @change="
                                            () => {
                                                targetState.modalForm.associationProjectId = undefined
                                                targetState.modalForm.projectId = undefined
                                                targetState.modalForm.teamLeaderList = []
                                                targetState.modalForm.participantsList = []
                                            }
                                        "
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="11">
                                <a-form-item
                                    label="项目名称"
                                    :rules="[{ required: true, message: '请选择项目名称', trigger: 'blur' }]"
                                    name="projectId"
                                >
                                    <a-select
                                        :disabled="currentEditData.overallProjectId"
                                        :options="targetState.projectList"
                                        v-model:value="targetState.modalForm.projectId"
                                        :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :placeholder="selectHolder"
                                        @focus="getProjectListAccordingType"
                                        @change="
                                            () => {
                                                setTeamLeader()
                                                targetState.modalForm.participantsList = []
                                            }
                                        "
                                    />
                                </a-form-item>
                            </a-col>
                            <a-divider style="margin-bottom: 16px; margin-top: 0" />
                            <a-col :span="22">
                                <a-form-item
                                    label="项目总目标"
                                    :rules="[{ required: true, message: '请输入项目总目标', trigger: 'blur' }]"
                                    name="totalMonthlyGoal"
                                >
                                    <a-textarea
                                        v-model:value="targetState.modalForm.totalMonthlyGoal"
                                        :placeholder="inputHolder"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="11">
                                <a-form-item
                                    label="团队负责人"
                                    :rules="[{ required: true, message: '请选择团队负责人', trigger: 'blur' }]"
                                    name="teamLeaderList"
                                >
                                    <a-select
                                        :placeholder="selectHolder"
                                        show-search
                                        mode="multiple"
                                        :options="targetState.allUser"
                                        v-model:value="targetState.modalForm.teamLeaderList"
                                        :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="11">
                                <a-form-item
                                    label="负责人"
                                    :rules="[{ required: true, message: '请选择负责人', trigger: 'blur' }]"
                                    name="leaderList"
                                >
                                    <a-select
                                        show-search
                                        mode="multiple"
                                        :placeholder="selectHolder"
                                        :options="targetState.allUser"
                                        v-model:value="targetState.modalForm.leaderList"
                                        :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="22">
                                <a-form-item
                                    label="团队成员"
                                    :rules="[{ required: true, message: '请选择团队成员', trigger: 'blur' }]"
                                    name="participantsList"
                                >
                                    <a-select
                                        :placeholder="selectHolder"
                                        show-search
                                        mode="multiple"
                                        :options="targetState.allUser"
                                        v-model:value="targetState.modalForm.participantsList"
                                        :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col v-if="lastPeopleList.length > 0" :span="22">
                                <div style="width: 600px; margin-left: 100px; margin-bottom: 28px">
                                    <a
                                        href="javascript:;"
                                        v-for="(item, num) in lastPeopleList"
                                        @click="handlerAddLastPeople(item.value)"
                                        ><span style="margin: 0 5px">{{ item.value }}</span></a
                                    >
                                </div>
                            </a-col>
                            <a-col :span="24">
                                <div v-for="(item, index) in targetState.modalForm.monthlyGoalObjectList" :key="index">
                                    <a-row>
                                        <a-col :span="22">
                                            <a-form-item
                                                label="子目标"
                                                :rules="[{ required: true, message: '请输入子目标', trigger: 'blur' }]"
                                                :name="['monthlyGoalObjectList', index, 'monthlyGoal']"
                                            >
                                                <a-textarea
                                                    v-model:value="
                                                        targetState.modalForm.monthlyGoalObjectList[index].monthlyGoal
                                                    "
                                                    :placeholder="inputHolder"
                                                />
                                            </a-form-item>
                                        </a-col>
                                        <a-col :span="2">
                                            <a-button @click="handleDeleteTargetItem(index)" type="link">删除</a-button>
                                        </a-col>
                                        <a-col :span="22">
                                            <a-form-item
                                                label="验收标准"
                                                :rules="[
                                                    { required: true, message: '请输入验收标准', trigger: 'blur' }
                                                ]"
                                                :name="['monthlyGoalObjectList', index, 'acceptanceCriteria']"
                                            >
                                                <a-textarea
                                                    v-model:value="
                                                        targetState.modalForm.monthlyGoalObjectList[index]
                                                            .acceptanceCriteria
                                                    "
                                                    :placeholder="inputHolder"
                                                />
                                            </a-form-item>
                                        </a-col>
                                    </a-row>
                                </div>
                            </a-col>
                            <a-col :span="22">
                                <a-button @click="handleAddTargetItem" type="primary" ghost
                                    ><template #icon><plus-outlined /></template> 新增</a-button
                                >
                            </a-col>
                        </a-row>
                    </a-form>
                </div>
            </a-modal>
            <!--        新建/编辑月度目标    -->
            <div class="body">
                <div class="top-search">
                    <a-row>
                        <a-col :span="21">
                            <a-row>
                                <a-col :span="6" v-if="targetState.radioValue === '月度目标'">
                                    <a-form-item :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }" label="月份筛选">
                                        <a-range-picker
                                            style="width: 100%"
                                            picker="month"
                                            :allow-clear="false"
                                            v-model:value="state.searchForm.targetMonthList"
                                            value-format="YYYY-MM"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6" v-else>
                                    <a-form-item :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }" label="年份">
                                        <a-date-picker
                                            style="width: 100%"
                                            v-model:value="state.searchForm.year"
                                            picker="year"
                                            :allow-clear="false"
                                            value-format="YYYY"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6" v-if="targetState.radioValue === '月度目标'">
                                    <a-form-item :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }" label="项目类型">
                                        <a-select
                                            mode="multiple"
                                            :options="[
                                                {
                                                    label: '交付',
                                                    value: '交付'
                                                },
                                                {
                                                    label: '产品研发',
                                                    value: '产品研发'
                                                },
                                                {
                                                    label: '市场',
                                                    value: '市场'
                                                }
                                            ]"
                                            :placeholder="selectHolder"
                                            :filterOption="
                                                (input, option) => {
                                                    return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                }
                                            "
                                            show-search
                                            v-model:value="state.searchForm.projectTypeList"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6">
                                    <a-form-item :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }" label="项目名称">
                                        <a-select
                                            :mode="'multiple'"
                                            :options="state.projectList"
                                            v-model:value="state.searchForm.projectIdList"
                                            @focus="getProjectList"
                                            show-search
                                            :placeholder="selectHolder"
                                            :filterOption="
                                                (input, option) => {
                                                    return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                }
                                            "
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6" v-if="targetState.radioValue === '月度目标'">
                                    <a-form-item :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }" label="负责人">
                                        <a-select
                                            :mode="'multiple'"
                                            :options="state.allUser"
                                            v-model:value="state.searchForm.leaderList"
                                            @focus="getAllUser"
                                            show-search
                                            :placeholder="selectHolder"
                                            :filterOption="
                                                (input, option) => {
                                                    return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                }
                                            "
                                        />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                        </a-col>
                        <a-col
                            :span="3"
                            style="display: flex; flex-direction: row; justify-content: flex-end; align-items: start"
                        >
                            <a-space>
                                <a-button @click="getCheckData" type="primary">查询</a-button>
                                <a-button @click="resetData" type="primary" ghost>重置</a-button>
                            </a-space>
                        </a-col>
                    </a-row>
                </div>
                <div class="top-title">
                    <a-radio-group v-model:value="targetState.radioValue" button-style="solid" @change="getCheckData">
                        <a-radio-button value="月度目标">月度目标</a-radio-button>
                        <a-radio-button value="年度目标">年度目标</a-radio-button>
                    </a-radio-group>
                    <div class="title-right">
                        <a-space :size="16">
                            <a-button
                                v-if="targetState.radioValue === '月度目标'"
                                @click="handleExpendAll"
                                type="primary"
                                ghost
                                >{{ allExpanded ? '全部收起' : '全部展开' }}</a-button
                            >

                            <a-button
                                type="primary"
                                v-if="targetState.radioValue === '月度目标'"
                                @click="handleAddTarget"
                                v-permission="'3000001093_vid_isxswct1h6'"
                                >新建</a-button
                            >
                            <a-button
                                type="primary"
                                v-if="targetState.radioValue === '年度目标'"
                                @click="showAddOrEditYearGoal(null)"
                                v-permission="'3000001093_vid_gh4tjsaip4'"
                                >新建</a-button
                            >
                        </a-space>
                    </div>
                </div>

                <div class="content">
                    <a-spin :spinning="targetState.loading" tip="加载中">
                        <div class="no-data-image" v-if="targetState.dataSource.length == 0">
                            <div class="no-date-tip"> 暂无数据 </div>
                        </div>
                        <template v-if="targetState.radioValue === '月度目标'">
                            <div v-for="goal in targetState.dataSource" :key="goal.id" class="goal-card">
                                <div class="goal-title-bar">
                                    <div class="goal-info">
                                        <div class="goal-month ft16">{{ goal.targetMonth }}</div>
                                        <div class="goal-product-jf" v-if="goal.projectType === '交付'">{{
                                            goal.projectType
                                        }}</div>
                                        <div class="goal-product-cp" v-if="goal.projectType === '产品研发'">{{
                                            goal.projectType
                                        }}</div>
                                        <div class="goal-product-sc" v-if="goal.projectType === '市场'">{{
                                            goal.projectType
                                        }}</div>
                                        <div class="goal-name" :title="goal.projectName">{{ goal.projectName }}</div>
                                    </div>
                                    <div class="goal-ops">
                                        <div class="approve-img"></div>
                                        <div>
                                            <span class="ft-label">审批状态：</span>
                                            <span class="ft14">{{ goal.approvalStatus }}</span>
                                        </div>
                                        <div class="time-img"></div>
                                        <div>
                                            <span class="ft-label">提交时间：</span>
                                            <span class="ft14">{{ goal.modifiedTime }}</span>
                                        </div>
                                        <!--                                    <a-button type="link" size="small" class="btn-no-margin" @click="showHidden(goal)"-->
                                        <!--                                        >取消展示</a-button-->
                                        <!--                                    >-->
                                        <!--                                    <a-divider type="vertical" style="background-color: #3875ff; margin: 0" />-->
                                        <a-button
                                            type="link"
                                            size="small"
                                            class="btn-no-margin"
                                            v-permission="'3000001093_vid_008jlq241v'"
                                            @click="handleAssociation(goal)"
                                            >关联</a-button
                                        >
                                        <!--                                        <a-divider type="vertical" style="background-color: #3875ff; margin: 0" />-->
                                        <a-button
                                            type="link"
                                            size="small"
                                            v-permission="'3000001093_vid_0hmbaplbmh'"
                                            class="btn-no-margin"
                                            @click="showGante(goal)"
                                            >甘特图</a-button
                                        >
                                        <!--                                        <a-divider type="vertical" style="background-color: #3875ff; margin: 0" />-->
                                        <a-button
                                            type="link"
                                            size="small"
                                            class="btn-no-margin"
                                            @click="handleEditGoal(goal)"
                                            v-permission="'3000001093_vid_vljk3npb78'"
                                            >编辑</a-button
                                        >
                                        <!--                                        <a-divider type="vertical" style="background-color: #3875ff; margin: 0" />-->
                                        <a-popconfirm
                                            placement="left"
                                            title="确定删除吗?"
                                            ok-text="确定"
                                            cancel-text="取消"
                                            @confirm="confirmDeleteGoal(goal)"
                                            @cancel="cancel"
                                        >
                                            <a-button
                                                type="link"
                                                size="small"
                                                v-permission="'3000001093_vid_ork98p86ny'"
                                                class="btn-no-margin"
                                                >删除</a-button
                                            >
                                        </a-popconfirm>
                                    </div>
                                </div>
                                <div class="first-line">
                                    <div class="line-item">
                                        <div class="xs-img"></div>
                                        <span class="ft-label">完成系数：</span>
                                        <span class="ft14" :title="goal.finishCoefficient">{{
                                            goal.finishCoefficient
                                        }}</span>
                                    </div>
                                    <div class="line-item">
                                        <div class="trd-img"></div>
                                        <span class="ft-label">投入度总数：</span>
                                        <span class="ft14" :title="goal.investment">{{ goal.investment }}</span>
                                    </div>
                                    <div class="line-item">
                                        <div class="tl-img"></div>
                                        <span class="ft-label">团队负责人：</span>
                                        <span class="ft14" :title="goal.teamLeader">{{ goal.teamLeader }}</span>
                                    </div>
                                    <div class="line-item">
                                        <div class="fzr-img"></div>
                                        <span class="ft-label">负责人：</span>
                                        <span class="ft14" :title="goal.leader">{{ goal.leader }}</span>
                                    </div>
                                </div>
                                <div class="first-line">
                                    <div class="line-item">
                                        <div class="fzr-img"></div>
                                        <span class="ft-label">团队成员：</span>
                                        <span class="ft14" :title="goal.participants">{{ goal.participants }}</span>
                                    </div>
                                </div>
                                <div class="second-line">
                                    <div class="line-item">
                                        <div class="zmb-img"></div>
                                        <span class="ft-label">月度总目标：</span>
                                        <span class="ft14" :title="goal.totalMonthlyGoal">{{
                                            goal.totalMonthlyGoal
                                        }}</span>
                                    </div>
                                </div>
                                <a-divider style="margin: 16px 0; background-color: rgba(56, 117, 255, 0.3)" />
                                <!-- 子目标 -->
                                <div v-for="sub in goal.monthlyGoalTaskDtoList" :key="sub.id" class="sub-target-box">
                                    <div class="sub-header" @click="toggleSubTarget(sub)">
                                        <span
                                            class="arrow-icon"
                                            :class="{ rotated: expandedSet.has(sub.id) }"
                                            v-if="
                                                (sub.storyList && sub.storyList.length > 0) ||
                                                (sub.taskList && sub.taskList.length > 0)
                                            "
                                            ><RightOutlined style="font-size: 12px; color: #262626"
                                        /></span>
                                        <div v-else style="margin-right: 20px"></div>
                                        <span class="sub-name">{{ sub.projectMonthlyGoal }}</span>
                                    </div>
                                    <div class="sub-desc" @click="toggleSubTarget(sub)">
                                        <div style="margin-right: 20px"></div>
                                        <template
                                            v-if="
                                                (sub.taskList && sub.taskList.length) ||
                                                (sub.storyList && sub.storyList.length)
                                            "
                                        >
                                            <!--                    <div class="ft-label" >完成状态：</div>-->
                                            <div class="tags-group-suolv">
                                                <div
                                                    class="tag-item"
                                                    v-for="(story, index) in sub.taskList"
                                                    :title="story.taskStatus"
                                                    :style="{ backgroundColor: getStatusColor(story.taskStatus) }"
                                                    >{{ index }}</div
                                                >
                                                <div class="tag-item-group" v-for="(story, index) in sub.storyList">
                                                    <div
                                                        class="tag-item"
                                                        :title="story.storyStatus"
                                                        :style="{
                                                            backgroundColor: getStatusColor(story.storyStatus)
                                                        }"
                                                    ></div>
                                                </div>
                                            </div>
                                        </template>
                                        <div class="ft-label">验收标准：</div>
                                        <div class="ft14 space-memory">{{ sub.acceptanceCriteria || '无' }}</div>
                                    </div>

                                    <div
                                        v-show="expandedSet.has(sub.id)"
                                        class="story-slot-wrapper"
                                        style="margin: 0 24px"
                                    >
                                        <div
                                            class="story-item"
                                            v-for="(story, index) in sub.taskList"
                                            :key="story.id"
                                            v-if="goal.projectType === '交付' || goal.projectType === '市场'"
                                        >
                                            <div class="story-title">
                                                <div class="title-left">
                                                    <div
                                                        class="priority-tag"
                                                        title="优先级"
                                                        v-if="story.priority"
                                                        :style="{ backgroundColor: getBgc(story.priority) }"
                                                        >{{ story.priority }}</div
                                                    >
                                                    <div
                                                        title="用户故事状态"
                                                        class="status-tag"
                                                        :style="{
                                                            backgroundColor: getStatusColor(story.taskStatus)
                                                        }"
                                                        >{{ story.taskStatus }}</div
                                                    >

                                                    <div class="story-name" :title="story.taskName">{{
                                                        story.taskName
                                                    }}</div>
                                                </div>
                                                <div class="title-right task-title-right">
                                                    <a-space :size="8">
                                                        <div class="people-icon"></div>
                                                        <span class="title">创建人 :</span>
                                                        <span class="msg">{{ story.createBy }}</span>

                                                        <div class="time-icon"></div>
                                                        <span class="title">创建时间 :</span>
                                                        <span class="msg">{{ story.createTime }}</span>

                                                        <a-popconfirm
                                                            title="确定取消关联吗?"
                                                            ok-text="确定"
                                                            cancel-text="取消"
                                                            @confirm="cnacelTask(story.taskId, sub)"
                                                            @cancel="cancel"
                                                        >
                                                            <a-button
                                                                style="padding: 0"
                                                                v-permission="'3000001093_vid_h55tfmeusw'"
                                                                type="link"
                                                                size="small"
                                                                >取消关联</a-button
                                                            >
                                                        </a-popconfirm>
                                                    </a-space>
                                                </div>
                                            </div>
                                            <div class="content-body">
                                                <div class="story-content">
                                                    <div class="item-icon"> </div>
                                                    <a-descriptions title="" bordered :column="4" size="small">
                                                        <a-descriptions-item label="项目阶段">
                                                            <div class="item-content" :title="story.milepostName">{{
                                                                story.milepostName
                                                            }}</div>
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="任务负责人">
                                                            <div class="item-content" :title="story.taskOwner">{{
                                                                story.taskOwner
                                                            }}</div>
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="任务执行人">
                                                            <div
                                                                class="item-content"
                                                                :title="story.taskParticipantStr"
                                                                >{{ story.taskParticipantStr }}</div
                                                            >
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="审核员">
                                                            <div class="item-content" :title="story.assessorName">{{
                                                                story.assessorName
                                                            }}</div>
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="计划开始">
                                                            <div class="item-content" :title="story.startTime">{{
                                                                story.startTime
                                                            }}</div>
                                                        </a-descriptions-item>

                                                        <a-descriptions-item label="计划结束">
                                                            <div class="item-content" :title="story.endTime">{{
                                                                story.endTime
                                                            }}</div>
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="实际开始">
                                                            <div class="item-content" :title="story.examPassTime">{{
                                                                story.examPassTime
                                                            }}</div>
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="实际结束">
                                                            <div
                                                                class="item-content"
                                                                :title="story.actualTaskFinishTime"
                                                                >{{ story.actualTaskFinishTime }}</div
                                                            >
                                                        </a-descriptions-item>
                                                    </a-descriptions>
                                                    <!-- 第一行 -->
                                                </div>
                                            </div>
                                        </div>
                                        <div
                                            class="story-item"
                                            v-for="(story, index) in sub.storyList"
                                            :key="story.id"
                                            v-if="goal.projectType === '产品研发'"
                                        >
                                            <div class="story-title">
                                                <div class="title-left">
                                                    <div class="version-div">
                                                        <span class="title">版本号 :</span>
                                                        <span class="msg">{{
                                                            story.iterationVersionName || '暂无'
                                                        }}</span>
                                                    </div>
                                                    <div
                                                        class="priority-tag"
                                                        title="优先级"
                                                        v-if="story.priority"
                                                        :style="{ backgroundColor: getBgc(story.priority) }"
                                                        >{{ story.priority }}</div
                                                    >
                                                    <div
                                                        title="用户故事状态"
                                                        class="status-tag"
                                                        :style="{
                                                            backgroundColor: getStatusColor(story.storyStatus)
                                                        }"
                                                        >{{ story.storyStatus }}</div
                                                    >

                                                    <div class="story-name" :title="story.storyName">{{
                                                        story.storyName
                                                    }}</div>
                                                </div>
                                                <div class="title-right">
                                                    <div class="title">任务进度:</div>

                                                    <a-tooltip>
                                                        <template #title>
                                                            <div>
                                                                <div>任务总数{{ story.taskNumber }}个</div>
                                                                <div class="flex-color">
                                                                    <div class="no-start"></div>
                                                                    <div
                                                                        >未开始任务数{{
                                                                            story.noStartTaskNumber
                                                                        }}个</div
                                                                    >
                                                                </div>
                                                                <div class="flex-color">
                                                                    <div class="running"></div>
                                                                    <div
                                                                        >进行中任务数{{
                                                                            story.runningTaskNumber
                                                                        }}个</div
                                                                    >
                                                                </div>
                                                                <div class="flex-color">
                                                                    <div class="finish"></div>
                                                                    <div
                                                                        >已完成任务数{{ story.finishTaskNumber }}个</div
                                                                    >
                                                                </div>
                                                            </div>
                                                        </template>
                                                        <div style="display: flex; gap: 8px">
                                                            <a-progress
                                                                style="width: 150px; margin-right: 8px"
                                                                :percent="totalPercent(story)"
                                                                :success="{
                                                                    percent: finishPercent(story),
                                                                    strokeColor: '52c41a'
                                                                }"
                                                                :show-info="false"
                                                                trailColor="#d9d9d9"
                                                                strokeColor="#3875ff"
                                                            />
                                                            <div
                                                                >{{
                                                                    formatPercentage(
                                                                        story.taskNumber
                                                                            ? (story.finishTaskNumber /
                                                                                  story.taskNumber) *
                                                                                  100
                                                                            : 0
                                                                    )
                                                                }}%</div
                                                            >
                                                        </div>
                                                    </a-tooltip>
                                                    <div class="people-icon"></div>
                                                    <div class="title">负责人 :</div>
                                                    <div class="msg" :title="story.owner">{{ story.owner }}</div>

                                                    <div class="time-icon"></div>
                                                    <div class="title">计划完成时间 :</div>
                                                    <div class="msg no-flex">{{ story.endTime }}</div>
                                                    <a-button
                                                        size="small"
                                                        type="link"
                                                        @click="showQuestionMsg(story.description)"
                                                        >查看描述</a-button
                                                    >

                                                    <a-popconfirm
                                                        title="确定取消关联吗?"
                                                        ok-text="确定"
                                                        cancel-text="取消"
                                                        @confirm="cnacelStory(story.id, sub)"
                                                        @cancel="cancel"
                                                    >
                                                        <a-button
                                                            type="link"
                                                            v-permission="'3000001093_vid_h55tfmeusw'"
                                                            style="padding: 0"
                                                            size="small"
                                                            >取消关联</a-button
                                                        >
                                                    </a-popconfirm>
                                                </div>
                                            </div>
                                            <div class="content-body">
                                                <div class="story-content">
                                                    <div class="item-icon" v-if="story.labels">
                                                        <div
                                                            v-for="(tag, index) in handlerGetSpace(story.labels)"
                                                            class="label-item"
                                                        >
                                                            <div class="label-img"></div>{{ tag }}
                                                        </div>
                                                    </div>
                                                    <a-descriptions title="" bordered :column="6" size="small">
                                                        <a-descriptions-item label="计划开始">
                                                            <div class="item-content" :title="story.startTime">{{
                                                                story.startTime
                                                            }}</div>
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="实际开始">
                                                            <div class="item-content" :title="story.actualStartTime">{{
                                                                story.actualStartTime
                                                            }}</div>
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="计划完成">
                                                            <div class="item-content" :title="story.endTime">{{
                                                                story.endTime
                                                            }}</div>
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="实际完成">
                                                            <div class="item-content" :title="story.actualEndTime">{{
                                                                story.actualEndTime
                                                            }}</div>
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="任务总数">
                                                            <div
                                                                class="item-content"
                                                                style="cursor: pointer; color: #3875ff"
                                                                :title="story.taskNumber"
                                                                @click="showTaskModal(story.id)"
                                                                >{{ story.taskNumber }}</div
                                                            >
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="进行中任务数">
                                                            <div
                                                                class="item-content"
                                                                style="color: #262626"
                                                                :title="story.runningTaskNumber"
                                                                @click="showTaskModal(story.id)"
                                                                >{{ story.runningTaskNumber }}</div
                                                            >
                                                        </a-descriptions-item>
                                                        <a-descriptions-item label="备注" :span="5">
                                                            <div class="item-content" :title="story.remark">{{
                                                                story.remark
                                                            }}</div>
                                                        </a-descriptions-item>
                                                    </a-descriptions>
                                                    <!-- 第一行 -->
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <a-divider
                                    style="margin: 16px 0; background-color: rgba(56, 117, 255, 0.3)"
                                    v-if="index == state.dataSource.length - 1"
                                />
                            </div>
                        </template>
                        <template v-else>
                            <div v-for="goal in targetState.yearDataSource" :key="goal.id" class="goal-card">
                                <div class="goal-title-bar">
                                    <div class="goal-info">
                                        <div class="goal-month ft16">{{ goal.targetMonth }}</div>
                                        <div class="goal-product-jf" v-if="goal.projectType === '交付'">{{
                                            goal.projectType
                                        }}</div>
                                        <div class="goal-product-cp" v-if="goal.projectType === '产品研发'">{{
                                            goal.projectType
                                        }}</div>
                                        <div class="goal-product-sc" v-if="goal.projectType === '市场'">{{
                                            goal.projectType
                                        }}</div>
                                        <div class="goal-name" :title="goal.projectName">{{ goal.projectName }}</div>
                                    </div>
                                    <div class="goal-ops" style="padding-right: 24px">
                                        <div style="margin-right: 8px"
                                            ><span class="label">创建时间:</span>
                                            <span class="value">{{ goal.updateTime }}</span>
                                        </div>
                                        <div style="margin-right: 8px"
                                            ><span class="label">创建人:</span>
                                            <span class="value">{{ goal.updateBy }}</span>
                                        </div>
                                        <a-button
                                            type="link"
                                            size="small"
                                            class="btn-no-margin"
                                            @click="showAddOrEditYearGoal(goal)"
                                            v-permission="'3000001093_vid_9cotfiii2c'"
                                            >编辑</a-button
                                        >
                                        <!--                                        <a-divider-->
                                        <!--                                            type="vertical"-->
                                        <!--                                            style="background-color: #3875ff; margin: 0"-->
                                        <!--                                        />-->
                                        <a-popconfirm
                                            placement="left"
                                            title="确定删除吗?"
                                            ok-text="确定"
                                            cancel-text="取消"
                                            @confirm="confirmDeleteYearGoal(goal)"
                                            @cancel="cancel"
                                        >
                                            <a-button
                                                type="link"
                                                size="small"
                                                v-permission="'3000001093_vid_bhwmspfdgf'"
                                                class="btn-no-margin"
                                                >删除</a-button
                                            >
                                        </a-popconfirm>
                                    </div>
                                </div>
                                <!-- 子目标 -->
                                <a-descriptions
                                    bordered
                                    size="small"
                                    :label-style="{ width: '100px', backgroundColor: '#f2f6fc' }"
                                >
                                    <a-descriptions-item label="年度目标">
                                        <a-tooltip>
                                            <template #title> {{ goal.yearGoals }}</template>
                                            <div class="desc-value">
                                                {{ goal.yearGoals || '--' }}
                                            </div>
                                        </a-tooltip>
                                    </a-descriptions-item>
                                </a-descriptions>
                            </div>
                        </template>
                    </a-spin>
                </div>
            </div>
            <div class="pagination-div">
                <a-pagination
                    v-model:current="pagination.current"
                    :total="pagination.total"
                    :show-total="pagination.showTotal"
                    :page-size="pagination.pageSize"
                    :show-size-changer="true"
                    @change="pageChange"
                />
            </div>
            <!-- end vid_p2x31ulxw6 自定义模板_gufjjaz2ct -->
            <!-- begin vid_w7zzsiss6f 容器_q08c8hk2as -->
            <al-box v-if="false" class="vid_w7zzsiss6f">
                <!-- begin vid_isxswct1h6 新建 -->
                <a-button v-permission="'3000001093_vid_isxswct1h6'" class="vid_isxswct1h6"> 新建 </a-button>
                <!-- end vid_isxswct1h6 新建 -->
                <!-- begin vid_vljk3npb78 编辑 -->
                <a-button v-permission="'3000001093_vid_vljk3npb78'" class="vid_vljk3npb78"> 编辑 </a-button>
                <!-- end vid_vljk3npb78 编辑 -->
                <!-- begin vid_ork98p86ny 删除 -->
                <a-button v-permission="'3000001093_vid_ork98p86ny'" class="vid_ork98p86ny"> 删除 </a-button>
                <!-- end vid_ork98p86ny 删除 -->
                <!-- begin vid_008jlq241v 关联 -->
                <a-button v-permission="'3000001093_vid_008jlq241v'" class="vid_008jlq241v"> 关联 </a-button>
                <!-- end vid_008jlq241v 关联 -->
                <!-- begin vid_f474iqmj5j 项目配置 -->
                <a-button v-permission="'3000001093_vid_f474iqmj5j'" class="vid_f474iqmj5j"> 项目配置 </a-button>
                <!-- end vid_f474iqmj5j 项目配置 -->
                <!-- begin vid_0hmbaplbmh 甘特图 -->
                <a-button v-permission="'3000001093_vid_0hmbaplbmh'" class="vid_0hmbaplbmh"> 甘特图 </a-button>
                <!-- end vid_0hmbaplbmh 甘特图 -->
                <!-- begin vid_e8d1qz4ux7 生成绩效 -->
                <a-button v-permission="'3000001093_vid_e8d1qz4ux7'" class="vid_e8d1qz4ux7"> 生成绩效 </a-button>
                <!-- end vid_e8d1qz4ux7 生成绩效 -->
                <!-- begin vid_bv6ql52jgn 批量修改完成系数 -->
                <a-button v-permission="'3000001093_vid_bv6ql52jgn'" class="vid_bv6ql52jgn">
                    批量修改完成系数
                </a-button>
                <!-- end vid_bv6ql52jgn 批量修改完成系数 -->
                <!-- begin vid_h55tfmeusw 取消关联 -->
                <a-button v-permission="'3000001093_vid_h55tfmeusw'" class="vid_h55tfmeusw"> 取消关联 </a-button>
                <!-- end vid_h55tfmeusw 取消关联 -->
            </al-box>
            <!-- end vid_w7zzsiss6f 容器_q08c8hk2as -->
        </a-spin>
    </div>
</template>
<script setup lang="tsx">
    import {
        h,
        ref,
        reactive,
        toRaw,
        markRaw,
        watch,
        computed,
        onBeforeMount,
        onMounted,
        onBeforeUnmount,
        onUnmounted,
        onActivated,
        onDeactivated
    } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    const router = useRouter()
    const route = useRoute()
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios'
    import {
        cloneDeep,
        localGet,
        merge,
        getDifferenceArray,
        traversalTreeStructure,
        checkCaseCondition,
        renderStringInTemplate,
        handleBreadcrumbJump,
        throttle,
        permission,
        getComponentParamsValue
    } from '@/utils/index'
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is'
    import dayjs from 'dayjs'
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart'
    import { message, notification, Modal } from 'ant-design-vue'
    import {
        propertyFormatByNumber,
        propertyFormatByPercentage,
        propertyFormatByDate,
        parseSubFromDataList
    } from '@/utils/format'
    import colorTheme from '@/design/custom-theme.json'
    /*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/

    // 获取传入的流程ID和组件参数
    const props = defineProps({
        'processInstanceId': {
            type: [String, Number, Boolean],
            default: undefined
        }
    })
    const immediateWatch = (source, callback) => {
        watch(source, callback, { deep: true, immediate: true })
    }

    /* -------------------------- 属性定义 -------------------------- */

    const setTimeOutList = []
    const pageLoading = reactive({
        loading: false,
        tip: undefined
    })
    const authInfo = localGet('app-user-store')

    // 处理校验
    const setSubFormName = (parentInfo, name) => {
        return [parentInfo.parents, parentInfo.cycleIndex, name]
    }

    /* ========================== 属性定义 ========================== */

    /* -------------------------- 元素数据引用 -------------------------- */

    /* ========================== 元素数据引用 ========================== */

    /* -------------------------- 页面数据 -------------------------- */

    /* ========================== 页面数据 ========================== */

    /* -------------------------- 响应 -------------------------- */

    /* ========================== 响应 ========================== */

    /* -------------------------- 函数 -------------------------- */

    /* ========================== 函数 ========================== */

    /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId
    })

    /* ========================== 页面参数 ========================== */

    /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================

    /* ========================== 组件事件处理方法 ========================== */

    /* -------------------------- 生命周期 -------------------------- */
    // 用于参数变更后重新执行自定义指令
    const queryUpdateFlag = ref(0)
    onMounted(() => {})

    onUnmounted(() => {
        // 销毁定时器
        setTimeOutList.forEach(({ repeat, timer }) => {
            repeat ? clearInterval(timer) : clearTimeout(timer)
        })
    })

    /* ========================== 生命周期 ========================== */

    /* -------------------------- 数据关联处理 -------------------------- */

    /* -------------------------- 表单数据同步 -------------------------- */
    /* ========================== 表单数据同步 ========================== */

    /* ========================== 数据关联处理 ========================== */

    /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

    /* ========================== 不同组件自定义的处理逻辑 ========================== */

    // ================================定制化逻辑========================================
    const selectHolder = '请选择'
    const inputHolder = '请输入'
    let currentYear = dayjs().format('YYYY')
    let currentYearMonth = [`${dayjs().format('YYYY')}-01`, `${dayjs().format('YYYY')}-12`]
    onMounted(() => {
        state.searchForm.targetMonthList = currentYearMonth
        state.searchForm.year = currentYear
        getAllJfPeople()
        getCheckData()
    })
    const peopleList = ref([])

    function getAllJfPeople() {
        get('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/allUser').then(({ data }) => {
            peopleList.value = data.userDtoList.map(item => {
                return {
                    label: item.name,
                    value: item.id
                }
            })
        })
    }

    const state = reactive({
        searchForm: {
            leaderList: [],
            projectIdList: [],
            projectTypeList: [],
            targetMonthList: [],
            year: undefined
        },

        loading: false,
        dataSource: [],
        projectList: [],
        allUser: [],
        completeVisible: false,
        okLoading: false,
        type: '完成系数',
        settingVisble: false,
        treeData: [],
        filter: {
            month: []
        }
    })
    const pageChange = (page, pageSize) => {
        pagination.value.current = page
        pagination.value.pageSize = pageSize
        if (targetState.radioValue === '月度目标') {
            getData()
        } else {
            getYearGoal()
        }
    }
    const pagination = ref({
        current: 1,
        pageSize: 10,
        total: 0,
        pageSizeOptions: ['20', '40', '60', '80', '100'],
        showTotal: total =>
            `共 ${total} 个项目 第 ${pagination.value.current}/${Math.ceil(total / pagination.value.pageSize)}页`
    })

    //     获取项目列表
    function getProjectList() {
        get('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/platformAndDeliveryProjects').then(data => {
            state.projectList = data.data.projectDtoList.map(item => {
                return {
                    label: item.projectName,
                    value: item.projectId
                }
            })
        })
    }

    //     获取项目列表
    function getProjectListAccordingType() {
        post('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/projectNames', {
            projectType: targetState.modalForm.projectType
        }).then(data => {
            targetState.projectList = data.data.projectDtoList.map(item => {
                return {
                    label: item.projectName,
                    value: item.projectId,
                    people: item.teamLeaderList
                }
            })
        })
    }
    //     获取项目列表
    function getYearProjectListAccordingType() {
        post('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/projectNames', {
            projectType: targetState.yearGoalModalForm.projectType
        }).then(data => {
            targetState.projectList = data.data.projectDtoList.map(item => {
                return {
                    label: item.projectName,
                    value: item.projectId,
                    people: item.teamLeaderList
                }
            })
        })
    }
    // 设置teamLeader
    function setTeamLeader() {
        targetState.modalForm.teamLeaderList = []
        let leader = targetState.projectList.find(item => item.value === targetState.modalForm.projectId)
        if (leader) {
            targetState.modalForm.teamLeaderList = leader.people
        }
        getLastPeople()
    }
    //     获取负责人
    function getAllUser() {
        get('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/allUser').then(data => {
            state.allUser = targetState.allUser = data.data.userDtoList.map(item => {
                return {
                    label: item.name,
                    value: item.name
                }
            })
        })
    }

    const form = ref(null)
    const activeKeys = ref([])

    function expendAll() {
        // 遍历每个顶层项目
        function recursiveExpand(data) {
            data.forEach(item => {
                // 将当前项目的 projectId 添加到 activeKeys 中
                activeKeys.value.push(item.projectId)

                // 如果存在 children 并且是数组，则继续展开子节点
                if (Array.isArray(item.children)) {
                    recursiveExpand(item.children)
                }
            })
        }

        // 调用递归函数
        recursiveExpand(state.treeData)
    }
    import { nextTick } from 'vue'
    import Gante from './Page3000001091.vue'
    import { QuillEditor } from '@vueup/vue-quill'

    const targetState = reactive({
        dataSource: [],
        yearDataSource: [],
        projectList: [],
        parentName: undefined,
        searchForm: {
            month: undefined
        },
        showCheck: false,
        targetLoadog: false,
        addOrEditVisible: false,
        addOrEditTitle: '',
        modalForm: {
            monthlyGoalObjectList: [],
            participantsList: [],
            leaderList: [],
            associationProjectId: undefined,
            projectType: undefined,
            projectId: undefined,
            targetMonth: undefined,
            teamLeaderList: [],
            totalMonthlyGoal: undefined
        },
        allUser: [],
        expendAll: false,
        loading: false,
        ganteVisible: false,
        hiddenVisible: false,
        generateLoading: false,
        yearGoalTitle: '',
        yearGoalModalForm: {
            year: undefined,
            goal: undefined,
            projectType: undefined,
            projectId: undefined
        },
        addOrEditYearGoalVisible: false,
        addOrEditYearGoalLoading: false,
        radioValue: '月度目标'
    })
    // 获取月度目标
    function getData() {
        targetState.loading = true
        return post('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/monthlyGoals', {
            ...state.searchForm,
            pageNum: pagination.value.current,
            pageSize: pagination.value.pageSize
        })
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return []
                }
                targetState.dataSource = data.data.monthlyGoalManagementDtoList
                pagination.value.total = data.data.totalElements
                return data.data.monthlyGoalManagementDtoList
            })
            .finally(() => {
                targetState.loading = false
            })
    }
    function getYearGoal() {
        post('/solution-ppm/api/v2/built-in-system-ppm/pdtm/year_goals', {
            'dateYear': state.searchForm.year,
            projectTypeList: state.searchForm.projectTypeList,
            projectIdList: state.searchForm.projectIdList,
            leaderList: state.searchForm.leaderList,
            pageNum: pagination.value.current,
            pageSize: pagination.value.pageSize
        }).then(data => {
            targetState.yearDataSource = data.data.dataList
            pagination.value.total = data.data.totalElements
        })
    }
    function getCheckData() {
        pagination.value.current = 1
        pagination.value.pageSize = 10
        if (targetState.radioValue === '月度目标') {
            getData()
        } else {
            getYearGoal()
        }
    }
    function resetData() {
        state.searchForm.leaderList = []
        state.searchForm.projectIdList = []
        state.searchForm.projectTypeList = []
        state.searchForm.targetMonthList = currentYearMonth
        state.searchForm.year = currentYear
        getCheckData()
    }

    const formRef = ref(null)
    const targetFormRef = ref(null)
    const targetItem = {
        monthlyGoal: undefined,
        acceptanceCriteria: undefined,
        goalWeight: ''
    }

    function handleAddTargetItem() {
        targetState.modalForm.monthlyGoalObjectList.push({ ...targetItem })
    }

    function handleDeleteTargetItem(index) {
        targetState.modalForm.monthlyGoalObjectList.splice(index, 1)
    }

    function handleAddTarget() {
        targetState.addOrEditVisible = true
        targetState.addOrEditTitle = '新建目标'
        getAllUser()
        // getParentName()
        targetState.modalForm.monthlyGoalObjectList.push({ ...targetItem })
        currentEditData.value = {}
    }

    const allExpanded = ref(false)

    // const toggleSubTarget = sub => {
    //     sub.expanded = !sub.expanded
    // }
    function toggleSubTarget(sub) {
        if (expandedSet.has(sub.id)) {
            expandedSet.delete(sub.id)
        } else {
            expandedSet.add(sub.id)
        }
    }

    //     展开收起
    const handleExpendAll = () => {
        allExpanded.value = !allExpanded.value

        targetState.dataSource.forEach(goal => {
            goal.monthlyGoalTaskDtoList.forEach(sub => {
                if (allExpanded.value) {
                    expandedSet.add(sub.id)
                } else {
                    expandedSet.delete(sub.id)
                }
            })
        })
    }

    function handlerGetSpace(data) {
        return data?.split(/[,;；]/)
    }

    const colorMap = {
        '进行中': '#3875FF',
        '完成': '#52C41A',
        '未启动': '#8C8C8C',
        '未开始': '#8C8C8C',
        '已完成': '#52C41A',
        '延期': '#F5222D',
        '延期完成': '#FAAD14',
        '审批中': '#FAAD14',
        '下线': '#FAAD14',
        '已通过': '#52C41A'
    }

    function getStatusColor(status) {
        return colorMap[status] || '#8C8C8C'
    }

    const proityColor = {
        'P0': '#ff2a00',
        'P1': '#ffa940',
        'P2': '#ffa940',
        'P3': '#1890ff'
    }
    function getBgc(type) {
        type = type ? type.toUpperCase() : ''
        return proityColor[type]
    }

    //     用户故事
    const milepostState = reactive({
        searchForm: {
            storyStatus: undefined,
            storyName: undefined,
            directionField: 'created_time-desc',
            labels: undefined
        },
        current: 1,
        addOrEditVisible: false,
        addOrEditTitle: '',
        modalForm: {
            storyName: undefined,
            priority: undefined,
            labels: undefined,
            timeRangeList: [],
            taskList: [],
            templateTaskId: [],
            monthlyGoalTargetMonth: undefined,
            projectMonthlyGoalManagementId: undefined,
            remarks: undefined
        }
    })

    function cancelStory() {
        currentData.value = {}
        milepostState.addOrEditVisible = false
        milepostState.modalForm = {
            storyName: undefined,
            priority: undefined,
            labels: undefined,
            timeRangeList: [],
            taskList: [],
            templateTaskId: [],
            monthlyGoalTargetMonth: undefined,
            projectMonthlyGoalManagementId: undefined,
            remarks: undefined
        }
        milepostState.current = 1
    }

    const quillEditor = ref(null)
    const currentData = ref({})

    //     编辑story

    function getTarget() {
        post('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/monthlyGoals', {
            targetMonthList: [
                milepostState.modalForm.monthlyGoalTargetMonth,
                milepostState.modalForm.monthlyGoalTargetMonth
            ]
        }).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            const allSubGoals = []

            data.data.monthlyGoalManagementDtoList?.forEach(item => {
                item.monthlyGoalTaskDtoList?.forEach(sub => {
                    allSubGoals.push({
                        label: sub.projectMonthlyGoal,
                        value: sub.id
                    })
                })
            })
            milepostState.targetList = allSubGoals
        })
    }

    const showMsgState = reactive({
        visible: false,
        msg: undefined,
        title: ''
    })

    function showQuestionMsg(msg) {
        if (!msg) {
            message.info('暂无描述')
            return
        }
        showMsgState.msg = msg
        showMsgState.visible = true
    }

    function cancelShowMsg() {
        showMsgState.msg = undefined
        showMsgState.visible = false
    }

    //   格式化文本展示
    function getHtmlContent(input) {
        // 防御性处理：避免 null 或 undefined
        if (!input) return ''

        // 尝试解析为富文本 Delta 格式
        let deltaObj = null
        try {
            const parsed = typeof input === 'string' ? JSON.parse(input) : input
            if (parsed?.ops && Array.isArray(parsed.ops)) {
                deltaObj = parsed
            }
        } catch (e) {
            // 解析失败，说明不是 JSON 或不是 Delta 格式，走普通字符串逻辑
        }

        // 如果是富文本格式
        if (deltaObj) {
            try {
                const tempEl = document.createElement('div')
                const quill = new Quill(tempEl)
                quill.setContents(deltaObj)
                return quill.root.innerHTML
            } catch (err) {
                console.error('富文本渲染失败', err)
                return '' // 保险起见返回空
            }
        }

        // 否则是普通文本，做一下换行处理
        return String(input).replace(/\n/g, '<br/>')
    }

    //     富文本设置
    import { nextTick } from 'vue'
    import { QuillEditor, Quill } from '@vueup/vue-quill'
    import ImageUploader from 'quill-image-uploader'
    import '@vueup/vue-quill/dist/vue-quill.snow.css'

    const titleConfig = [
        { Choice: ' .ql-bold', title: '加粗' },
        { Choice: ' .ql-italic', title: '斜体' },
        { Choice: ' .ql-underline', title: '下划线' },
        { Choice: ' .ql-strike', title: '删除线' },
        { Choice: ' .ql-blockquote', title: '块引用' },
        { Choice: ' .ql-code-block', title: '插入代码' },
        { Choice: ' .ql-size', title: '字体大小' },
        { Choice: ' .ql-size', title: '字体大小' },
        { Choice: ' .ql-color', title: '字体颜色' },
        { Choice: ' .ql-background', title: '字体背景颜色' },
        { Choice: ' .ql-list[value="ordered"]', title: '有序列表' },
        { Choice: ' .ql-list[value="bullet"]', title: '无序列表' },
        { Choice: ' .ql-header[value="1"]', title: '1级标题' },
        { Choice: ' .ql-header[value="2"]', title: '2级标题' },
        { Choice: ' .ql-align', title: '对齐方式' },
        { Choice: ' .ql-clean', title: '清除字体格式' },
        { Choice: ' .ql-image', title: '图像' },
        { Choice: ' .ql-size .ql-picker-item[data-value="small"]', title: '小号' },
        { Choice: ' .ql-size .ql-picker-item[data-value="large"]', title: '大号' },
        { Choice: ' .ql-size .ql-picker-item[data-value="huge"]', title: '超大号' },
        { Choice: ' .ql-size .ql-picker-item:nth-child(2)', title: '标准' },
        { Choice: ' .ql-align .ql-picker-item:first-child', title: '居左对齐' },
        { Choice: ' .ql-align .ql-picker-item[data-value="center"]', title: '居中对齐' },
        { Choice: ' .ql-align .ql-picker-item[data-value="right"]', title: '居右对齐' },
        { Choice: ' .ql-align .ql-picker-item[data-value="justify"]', title: '两端对齐' }
    ]
    // 注册图片上传模块
    Quill.register('modules/imageUploader', ImageUploader)

    // 将本地文件转换为URL
    const getLocalImageURL = file => {
        return new Promise(resolve => {
            const reader = new FileReader()
            reader.onload = e => {
                resolve(e.target.result)
            }
            reader.readAsDataURL(file)
        })
    }

    // 表单数据

    // Quill 编辑器选项
    const editorOption = ref({
        modules: {
            // imageUploader: {
            //     upload: async file => {
            //         const localUrl = await getLocalImageURL(file)
            //         return localUrl // 返回本地图片的 URL 进行预览
            //     }
            // },
            toolbar: [
                ['bold', 'italic', 'underline', 'strike'], // 加粗，斜体，下划线，删除线
                ['blockquote', 'code-block'], // 引用，代码块
                [{ header: 1 }, { header: 2 }], // 标题1，标题2
                [{ list: 'ordered' }, { list: 'bullet' }], // 有序列表，无序列表
                [{ size: ['small', false, 'large', 'huge'] }], // 文字大小
                [{ color: [] }, { background: [] }], // 字体颜色，背景颜色
                [{ align: [] }], // 对齐
                ['clean'], // 清除格式
                ['image'] // 链接，图片，视频
            ]
            // ImageUploader: imageHandler
        }
    })
    // 上传API
    const uploadFileAPI = async file => {
        const data = new FormData()
        data.append('file', file)

        return post('/file-storage/api/v1/file/upload', data)
            .then(({ data: { fullUrl } }) => {
                return { data: { fullUrl } }
            })
            .catch(error => {
                console.error('上传图片出错:', error)
                throw error // 抛出错误以供外部处理
            })
    }

    // 将 dataURL 转换为 File 对象的辅助函数
    const dataURLtoFile = (dataurl, filename) => {
        const arr = dataurl.split(',')
        const mime = arr[0].match(/:(.*?);/)[1]
        const bstr = atob(arr[1])
        let n = bstr.length
        const u8arr = new Uint8Array(n)
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n)
        }
        return new File([u8arr], filename, { type: mime })
    }

    function initTitle() {
        document.getElementsByClassName('ql-editor')[0].dataset.placeholder = ''
        for (let item of titleConfig) {
            let tip = document.querySelector('.ql-toolbar' + item.Choice)
            if (!tip) continue
            tip.setAttribute('title', item.title)
        }
    }

    //     用户故事
    //     展示gante
    const gantMonth = ref()
    const gantProjectName = ref()

    function showGante(record) {
        gantMonth.value = record.targetMonth
        gantProjectName.value = record.projectId
        targetState.ganteVisible = true
    }

    function cancelGante() {
        targetState.ganteVisible = false
    }

    //     删除
    const currentHiddenData = ref({})

    function showHidden(record) {
        currentHiddenData.value = record
        targetState.hiddenVisible = true
    }

    // 编辑
    const currentEditData = ref({})

    function handleEditGoal(record) {
        getAllUser()
        get(`/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/monthlyGoals/${record.overallProjectId}`).then(data => {
            currentEditData.value = data.data
            Object.assign(targetState.modalForm, data.data)
            getProjectListAccordingType()
            getLastPeople()
            targetState.addOrEditVisible = true
            targetState.addOrEditTitle = '编辑目标'
        })
    }

    function submitTarget() {
        targetFormRef.value.validate().then(() => {
            const url = currentEditData.value.overallProjectId
                ? '/solution-ppm/api/v2/built-in-system-ppm/pmgf/edit/monthlyGoal'
                : '/solution-ppm/api/v2/built-in-system-ppm/pmgf/add/monthlyGoal'
            targetState.targetLoadog = true
            post(url, {
                ...targetState.modalForm,
                overallProjectId: currentEditData.value.overallProjectId ? currentEditData.value.overallProjectId : null
            })
                .then(data => {
                    if (data.code !== 200) {
                        message.error(data.message)
                        return
                    }
                    message.success(data.message)
                    cancelTarget()
                    getData()
                })
                .finally(() => {
                    targetState.targetLoadog = false
                })
        })
    }

    function cancelTarget() {
        targetState.addOrEditVisible = false
        targetState.modalForm = {
            monthlyGoalObjectList: [],
            participantsList: [],
            leaderList: [],
            associationProjectId: undefined,
            projectId: undefined,
            projectType: undefined,
            targetMonth: undefined,
            teamLeaderList: [],
            totalMonthlyGoal: undefined
        }
        lastPeopleList.value = []
        currentEditData.value = {}
    }

    function confirmDeleteGoal(goal) {
        del(`/solution-ppm/api/v2/built-in-system-ppm/pmgf/delete/monthlyGoals/${goal.overallProjectId}`).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            getData()
        })
    }

    //     关联
    function handleAssociation(goal) {
        window.open(
            `${import.meta.env.VITE_PUBLIC_PATH}/page/3000001102?projectId=${goal.projectId}&projectType=${
                goal.projectType
            }&id=${goal.overallProjectId}`,
            '_blank'
        )
    }
    const expandedSet = reactive(new Set()) // 用来存放展开的 sub.id
    //     取消关联
    function cnacelStory(id, sub) {
        del(`/solution-ppm/api/v2/built-in-system-ppm/pmgf/cancel/relatedStory/${id}`).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            // 保留需要展开的 ID
            expandedSet.add(sub.id)

            // 重新获取数据
            getData()
        })
    }

    function cnacelTask(id, sub) {
        del(`/solution-ppm/api/v2/built-in-system-ppm/pmgf/cancel/relatedTask/${id}`).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            expandedSet.add(sub.id)

            // 重新获取数据
            getData()
        })
    }
    // function jumpTask(type, versionId, projectId, storyId) {
    //     window.open(
    //         `${
    //             import.meta.env.VITE_PUBLIC_PATH
    //         }/page/3000001150?id=${projectId}&iterationVersionId=&taskStatus=${type}&storyId=${storyId}&jump=true`,
    //         '_blank'
    //     )
    // }
    function showTaskModal(id) {
        taskModalId.value = id
        taskMoadlVisible.value = true
    }
    const taskModalId = ref()
    const taskMoadlVisible = ref(false)
    import TaskJump from './Page3000001214.vue'
    const finishPercent = item => {
        const total = item.taskNumber || 1
        return (item.finishTaskNumber / total) * 100
    }

    const totalPercent = item => {
        const total = item.taskNumber || 1
        return ((item.finishTaskNumber + item.runningTaskNumber) / total) * 100
    }
    function formatPercentage(value) {
        if (value === 0) return '0'
        return value.toFixed(2)
    }
    function handlerAddLastPeople(name) {
        if (targetState.modalForm.participantsList.indexOf(name) !== -1) {
            targetState.modalForm.participantsList = targetState.modalForm.participantsList.filter(
                item => item !== name
            )
        } else {
            targetState.modalForm.participantsList.push(name)
        }
    }
    const lastPeopleList = ref([])
    function getLastPeople() {
        get(
            `/solution-ppm/api/v2/built-in-system-ppm/platform_product/product_participant/${targetState.modalForm.projectId}`
        ).then(data => {
            if (data.code !== 200) {
                lastPeopleList.value = []
                return
            }
            lastPeopleList.value = data.data.map(item => {
                return {
                    label: item,
                    value: item
                }
            })
        })
    }
    //     新建/编辑月度目标
    function showAddOrEditYearGoal(goal) {
        targetState.yearGoalModalForm.year = state.searchForm.year
        if (!goal) {
            targetState.yearGoalTitle = '新建年度目标'
            currentEditYearGoal.value = {}
        } else {
            currentEditYearGoal.value = goal
            targetState.yearGoalTitle = '编辑年度目标'
            targetState.yearGoalModalForm.year = goal.dateYear
            targetState.yearGoalModalForm.goal = goal.yearGoals
            targetState.yearGoalModalForm.projectId = goal.projectId
            targetState.yearGoalModalForm.projectType = goal.projectType
            getYearProjectListAccordingType()
        }
        targetState.addOrEditYearGoalVisible = true
    }
    function confirmDeleteYearGoal(goal) {
        del(`/solution-ppm/api/v2/built-in-system-ppm/pdtm/goals/${goal.id}`).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            getCheckData()
        })
    }
    const yearGoalRef = ref(null)
    const currentEditYearGoal = ref({})
    function handleSubmitYearGoal() {
        yearGoalRef.value.validate().then(() => {
            targetState.addOrEditYearGoalLoading = true
            put(`/solution-ppm/api/v2/built-in-system-ppm/pdtm/goals`, {
                'projectId': targetState.yearGoalModalForm.projectId,
                'projectType': targetState.yearGoalModalForm.projectType,
                'yearGoals': targetState.yearGoalModalForm.goal,
                'dateYear': targetState.yearGoalModalForm.year,
                'id': currentEditYearGoal.value.id
            })
                .then(data => {
                    if (data.code !== 200) {
                        message.error(data.message)
                        return
                    }
                    message.success(data.message)
                    resetYearGoal()
                    getYearGoal()
                })
                .finally(() => {
                    targetState.addOrEditYearGoalLoading = false
                })
        })
    }
    function resetYearGoal() {
        targetState.addOrEditYearGoalVisible = false
        targetState.yearGoalModalForm.year = undefined
        targetState.yearGoalModalForm.goal = undefined
        targetState.yearGoalModalForm.projectType = undefined
        targetState.yearGoalModalForm.projectId = undefined
        currentEditYearGoal.value = {}
    }
</script>
<style lang="less" scoped>
    .page_root {
        width: 100%;
        height: 100%;
        overflow: auto;
    }
    .page_root :deep(.@{ant-prefix}-spin-nested-loading),
    .page_root :deep(.@{ant-prefix}-spin-container) {
        height: 100%;
    }
    .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper) {
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
    }
    .page_root :deep(.@{ant-prefix}-table) {
        flex: auto;
        overflow: auto;
    }
    .table-moreBtn_down {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        width: 100px;
    }

    .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
        background: #ebf1ff;
    }

    /*  表格树结构样式处理，展开按钮层级增加*/
    :deep(.@{ant-prefix}-table-row-expand-icon) {
        z-index: 1;
    }
    /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
    :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 15px !important;
        width: calc(100% - 15px);
    }
    :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 30px !important;
        width: calc(100% - 30px);
    }
    :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 45px !important;
        width: calc(100% - 45px);
    }
    :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 60px !important;
        width: calc(100% - 60px);
    }

    /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
    :deep(.@{ant-prefix}-transfer-list) {
        height: 100%;
        width: 50%;
    }
    .vid_w7zzsiss6f {
        padding-top: 24px;
        padding-bottom: 24px;
        background-color: #ff0707;
    }
    .vid_isxswct1h6 {
        box-shadow: 0px 0px 0px 0px;
    }
    .vid_ork98p86ny {
        box-shadow: 0px 0px 0px 0px;
    }
    .vid_0hmbaplbmh {
        box-shadow: 0px 0px 0px 0px;
    }
    .vid_bv6ql52jgn {
        box-shadow: 0px 0px 0px 0px;
    }

    /*样式*/
    .body {
        overflow: hidden;
        position: relative;
        height: 100%;
    }
    .top-search {
        height: 64px;
        margin-bottom: 14px;
        padding: 16px 24px;
        padding-bottom: 10px;
        border-radius: 0px;
        background-color: #fff;
    }

    .top-title {
        display: flex;
        align-items: center;
        padding: 16px 24px 0;
        justify-content: space-between;
        background-color: #fff;
    }
    .title-msg {
        //padding-left: 8px;
        //font-weight: 800;
        //font-size: 16px;
        //line-height: 16px;
        //box-shadow: 0 0;
        //border-left-style: solid;
        //border-left-width: 4px;
        //border-left-color: #3875ff;
    }
    .title-msg:after {
        border: none !important;
    }
    .no-data-image {
        width: 66px;
        height: 80px;
        background-image: url('http://10.40.0.33:9001/file-storage/482099304502618112-source.png');
        background-size: cover;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
    .no-date-tip {
        font-size: 14px;
        color: #595959;
        letter-spacing: 0;
        font-weight: 400;
        margin-top: 84px;
    }
    .pagination-div {
        width: 100%;
        position: absolute;
        bottom: 0;
        padding: 10px;
        display: flex;
        justify-content: end;
        border-top: 1px solid #d9d9d9;
        background: #fff; /* 可选：为背景添加颜色 */
    }

    .modal-top-complete {
        margin-bottom: 16px;
    }
    .modal-top-setting {
        height: 40px;
        background: rgba(56, 117, 255, 0.1);
        border-radius: 0px;
        padding: 10px 16px;
        line-height: 20px;
        font-size: 14px;
        color: #262626;
        letter-spacing: 0;
        line-height: 20px;
        font-weight: 400;
        margin-bottom: 16px;
    }
    /*样式*/
    .modal-form :deep(.ant3-form-item-label) {
        width: 100px;
    }
    .reset-btn {
        color: #262626;
        background-color: #eeeeee;
        border-color: #eeeeee;
        border-radius: 0px;
    }
    .reset-btn:hover {
        background: #3875ff;
        border-color: #d9d9d9;
        color: #fff;
    }
    /*目标部分样式*/

    .goal-title-bar {
        height: 40px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 14px;
        padding-top: 10px;
        .ft16 {
            font-size: 14px;
            color: #262626;
            letter-spacing: 0;
            font-weight: 500;
        }
        .ft14 {
            font-size: 14px;
            color: #262626;
            letter-spacing: 0;
            font-weight: 500;
        }
        .ft-label {
            font-size: 14px;
            color: #595959;
            letter-spacing: 0;
            font-weight: 400;
        }
    }

    .goal-info {
        display: flex;
        gap: 8px;
        align-items: center;
        flex: 1;
        min-width: 0;
    }

    .goal-month {
        color: #1890ff;
        font-weight: 600;
    }

    .goal-product-jf,
    .goal-product-cp,
    .goal-product-sc {
        border-radius: 0px;
        width: 72px;
        height: 22px;
        text-align: center;
        font-size: 14px;
        letter-spacing: 0;
        line-height: 22px;
        font-weight: 500;
    }
    .goal-product-cp,
    .goal-product-sc {
        background: #722ed1;
        color: #fff;
    }
    .goal-product-jf {
        width: 44px;
        background: #f759ab;
        color: #fff;
    }

    .goal-name {
        color: #000;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        flex: 1;
        min-width: 0;
    }
    .goal-ops {
        display: flex;
        gap: 8px;
        align-items: center;
    }
    .label {
        color: #595959;
    }
    .value {
        color: #262626;
    }
    .approve-img,
    .time-img,
    .xs-img,
    .trd-img,
    .tl-img,
    .fzr-img,
    .zmb-img {
        width: 16px;
        height: 16px;
        background-size: cover;
        flex-shrink: 0; /* 防止标签被压缩 */
    }
    .approve-img {
        background-image: url('http://10.40.0.33:9001/file-storage/517613185818505216-source.png');
    }
    .time-img {
        margin-left: 8px;
        background-image: url('http://10.40.0.33:9001/file-storage/497178195155970048-source.png');
    }
    .xs-img {
        background-image: url('http://10.40.0.33:9001/file-storage/517613331111292928-source.png');
    }
    .trd-img {
        background-image: url('http://10.40.0.33:9001/file-storage/517613359385096192-source.png');
    }
    .tl-img {
        background-image: url('http://10.40.0.33:9001/file-storage/517613386515951616-source.png');
    }
    .fzr-img {
        background-image: url('http://10.40.0.33:9001/file-storage/517613418885492736-source.png');
    }
    .zmb-img {
        background-image: url('http://10.40.0.33:9001/file-storage/517613446855208960-source.png');
    }
    .btn-no-margin {
        padding: 0;
    }
    .first-line,
    .second-line {
        display: flex;
        gap: 24px;
        align-items: center;
        margin-bottom: 8px;
    }
    .line-item {
        display: flex;
        gap: 8px;
        align-items: center;
        min-width: 0; /* 允许.line-item收缩 */
        .ft14 {
            font-size: 14px;
            color: #262626;
            letter-spacing: 0;
            font-weight: 400;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            min-width: 0; /* 允许收缩 */
        }
        .ft-label {
            font-size: 14px;
            color: #595959;
            letter-spacing: 0;
            font-weight: 400;
            flex-shrink: 0; /* 防止标签被压缩 */
        }
    }

    .sub-target-box {
        margin-bottom: 20px;
    }
    .sub-target-box:last-child {
        margin-bottom: 0;
    }

    .sub-header {
        display: flex;
        align-items: center;
        justify-content: start;
        cursor: pointer;
        //white-space: pre-wrap;
    }

    .arrow-icon {
        font-size: 12px;
        transition: transform 0.2s;
        margin-right: 8px;
        color: #888;
    }

    .arrow-icon.rotated {
        transform: rotate(90deg);
    }

    .sub-name {
        font-size: 14px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
    }

    .sub-desc {
        font-size: 12px;
        color: #979797;
        letter-spacing: 0;
        font-weight: 600;
        display: flex !important;
        padding-bottom: 10px;
        cursor: pointer;
        display: flex;
        align-items: center;
        padding-top: 8px;
        .ft14 {
            font-size: 12px;
            color: #979797;
            letter-spacing: 0;
            font-weight: 500;
            flex: 1;
        }
        .ft-label {
            font-size: 12px;
            color: #979797;
            letter-spacing: 0;
            font-weight: 400;
        }
    }

    .expand-link {
        color: #1890ff;
        font-size: 14px;
        margin-left: 8px;
        white-space: nowrap;
    }

    .story-slot-wrapper {
        background: #fff;
        margin-bottom: 0 24px;
    }
    .story-item {
        box-shadow: 0 2px 5px 0 #c9dfff;
        border-radius: 0px;
        margin-bottom: 20px;
        .btn-opration {
            background-color: #ebf1ff;
            color: #3875ff;
        }
        :deep(.ant3-descriptions-view) {
            table {
                table-layout: fixed !important; /* 固定表格布局 */
                width: 100% !important;
                color: red;
            }
        }
        :deep(.ant3-descriptions-view) {
            table {
                table-layout: fixed !important; /* 固定表格布局 */
                width: 100% !important;
                color: red;
            }
        }
        :deep(.ant3-descriptions-bordered.ant3-descriptions-small .ant3-descriptions-item-label) {
            padding: 8px 8px;
        }
        :deep(.ant3-descriptions-bordered.ant3-descriptions-small .ant3-descriptions-item-content) {
            padding: 8px 8px;
        }
        .time-icon,
        .people-icon,
        .jz-icon {
            width: 16px;
            height: 16px;
            background-size: cover;
        }
        .time-icon {
            background-image: url('http://10.40.0.33:9001/file-storage/497178195155970048-source.png');
        }
        .people-icon {
            background-image: url('http://10.40.0.33:9001/file-storage/497178207099250688-source.png');
        }
        .story-name {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            flex: 1;
            min-width: 0; /* 必须设置 */
        }

        .story-title {
            width: 100%;
            display: flex;
            justify-content: space-between;
            background-image: linear-gradient(270deg, rgba(105, 173, 255, 0.05) 0%, rgba(56, 117, 255, 0.1) 100%);
            border-radius: 0;
            padding: 9px 24px;
            gap: 16px;
            align-items: center;
            left: 0;
        }
        .title-left {
            display: flex;
            gap: 8px;
            font-size: 16px;
            color: #262626;
            letter-spacing: 0;
            font-weight: 600;
            align-items: center;
            width: 40%;
            flex-shrink: 0;
            min-width: 0; /* 防止子元素撑破父容器 */
        }
        .title-right {
            display: flex;
            gap: 4px;
            align-items: center;
            min-width: 0; /* ⭐ 关键：允许压缩，触发省略 */
            flex: 1; /* 自适应剩余空间 */
            justify-content: end;
            .title,
            .people-icon,
            .time-icon {
                flex-shrink: 0;
            }
            .no-flex {
                flex-shrink: 0;
            }
            .msg {
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
            }
        }
        .status-tag,
        .priority-tag {
            font-size: 14px;
            color: #ffffff;
            letter-spacing: 0;
            text-align: center;
            line-height: 22px;
            padding: 0 4px;
            font-weight: 500;
            min-width: 32px;
            height: 22px;
            border-radius: 0;
            text-align: center;
        }
        .priority-tag {
            background: #40a9ff;
            border-radius: 0px;
            font-style: oblique;
        }
        .story-content {
            padding: 10px;
        }
        .item-title {
            white-space: nowrap;
            font-family: PingFangSC-Regular;
            font-size: 14px;
            color: #595959;
            letter-spacing: 0;
            text-align: right;
            font-weight: 400;
        }

        .item-content {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            cursor: default;
            font-family: PingFangSC-Medium;
            font-size: 14px;
            color: #262626;
            letter-spacing: 0;
            font-weight: 600;
        }
        .item-icon {
            display: flex;
            flex-wrap: wrap;
            gap: 8px; /* 可选：让 tag 之间有间距 */
            margin: 16px 0;
        }
        .label-item {
            display: flex;
            background-color: #eeeeee;
            align-items: center;
            padding: 1px 8px;
            font-size: 14px;
            color: #595959;
            letter-spacing: 0;
            text-align: center;
            font-weight: 400;
            gap: 4px;
            border-radius: 0px;
        }
        .label-img {
            background-image: url('http://10.40.0.33:9001/file-storage/503656902913648640-source.png');
            background-size: cover;
            width: 10px;
            height: 10px;
        }
        .target-item {
            align-items: center;
        }
    }
    .form-model :deep(.ant3-form-item-label) {
        width: 110px;
    }

    .content {
        padding: 16px 24px;
        background-color: #fff;
        border-radius: 0px;
        height: calc(100% - 194px);
        overflow: auto;

        /* 额外加个内层容器做 padding 避免问题 */
        display: flex;
        flex-direction: column;
    }
    .goal-card {
        flex: 1;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        background-image: linear-gradient(to bottom, #f2f6fc, #fff 80px);
        padding-left: 24px;
        padding-bottom: 16px;
        margin-bottom: 16px;
        box-shadow: 0 2px 8px #f2f6fc;
    }
    /*目标部分样式*/

    .tags-group-suolv {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        margin-right: 14px;
        padding-right: 14px;
        border-right: 1px solid #dcdfe6;
        height: 12px;
        gap: 1px;
        .tag-item-group {
            display: flex;
        }
        .tag-item {
            min-width: 10px;
            width: 10px;
            height: 8px;
            font-size: 0;
            &.tag-item-b {
                width: 2px;
            }
        }
    }
    .space-memory {
        white-space: break-spaces;
    }

    .version-div {
        font-size: 14px;
    }
    .flex-color {
        display: flex;
        gap: 4px;
        align-items: center;
    }
    .no-start,
    .running,
    .finish {
        width: 10px;
        height: 10px;
        border-radius: 50%;
    }
    .no-start {
        background-color: #d9d9d9;
    }
    .running {
        background-color: #3875ff;
    }
    .finish {
        background-color: #52c41a;
    }
    .desc-value {
        display: -webkit-box; /* 必须 */
        -webkit-box-orient: vertical; /* 必须 */
        -webkit-line-clamp: 3; /* 限制3行 */

        max-width: fit-content; /* 宽度随内容撑开 */
        max-height: 120px; /* 可选，和line-clamp保持一致 */

        overflow: hidden; /* 必须 */
        text-overflow: ellipsis; /* 必须 */

        white-space: pre-wrap; /* 保留换行符 */
        word-break: break-word; /* 自动换行 */
        cursor: pointer;
    }
</style>
